home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
assemblr
/
library
/
sampler0
/
vgamoire.asm
< prev
next >
Wrap
Assembly Source File
|
1989-03-09
|
8KB
|
473 lines
; VGAMOIRE.COM
; Structured pattern generator to show off the undocumented
; 320x400 256 color mode of the IBM VGA as revealed by
; Michael Abrash in his "On Graphics" column in the
; January/February 1989 issue of Programmer's Journal, Volume 7.1
VGA_SEGMENT equ 0A000h
SC_INDEX equ 3C4h
GC_INDEX equ 3CEh
CRTC_INDEX equ 3D4h
MAP_MASK equ 2
MEMORY_MODE equ 4
MAX_SCAN_LINE equ 9
START_ADDRESS_HIGH equ 0Ch
UNDERLINE equ 14h
MODE_CONTROL equ 17h
READ_MAP equ 4
GRAPHICS_MODE equ 5
MISCELLANEOUS equ 6
SCREEN_WIDTH equ 320
SCREEN_HEIGHT equ 400
tab equ 9
lf equ 10
cr equ 13
CONSTANT_TO_INDEXED_REGISTER macro ADDRESS, INDEX, VALUE
mov dx, ADDRESS
mov ax, (VALUE shl 8) + INDEX
out dx, ax
endm
code segment
org 100h
assume cs:code, ds:code
Begin:
push cs
pop ds
mov ax, VGA_SEGMENT
mov es, ax
call Set320x400Mode
mov ah, 2Ch
int 21h
mov Random, dx
mov si, 256 ; ColorCount
call Randy
mov bp, ax
call DoCircles
MainLoop:
call MakeRandomPalette
cmp PageNo, 0
je SetPage1
mov ax, 0A800h
mov es, ax
CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,0
mov PageNo, 0
jmp Start
SetPage1:
mov ax, 0A000h
mov es, ax
CONSTANT_TO_INDEXED_REGISTER CRTC_INDEX,START_ADDRESS_HIGH,80h
mov PageNo, 1
Start:
call Randy
and ax, 0003h
cmp al, 0
je Circ
cmp al, 1
je Sqar
cmp al, 2
je TiltCirc
jmp TiltSqar
Circ:
call Randy
inc ax
mov bp, ax
call DoCircles
jmp CheckKey
Sqar:
call Randy
inc ax
mov bp, ax
call DoSquares
jmp CheckKey
TiltCirc:
call Randy
inc ax
mov bp, ax
call DoTiltCircles
jmp CheckKey
TiltSqar:
call Randy
inc ax
mov bp, ax
call DoTiltSquares
CheckKey:
mov ah, 0Bh
int 21h
cmp al, 0
jne GetOut
jmp MainLoop
GetOut:
mov ax, 0003h ; Back to Text Mode
int 10h
mov ax, 4C00h
int 21h
PageNo dw 1
DoCircles proc near
mov bl, 00010001b ; Plane Mask bit
mov di, 0 ; Video memory pointer
mov cx, 0 ; For Y := 0 to 399 do
ForYCirc:
push cx
mov cx, 0 ; For X := 0 to 319 do
ForXCirc:
mov ax, bp ; Get IterateCnt
mul cx ; DX:AX := IterateCnt * X
add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
mov dx, SC_INDEX ; Select the correct plane
mov ah, bl
mov al, MAP_MASK
out dx, ax
mov ax, si ; Poke Color
mov byte ptr es:[di], al
rol bl, 1 ; Rotate for next plane
cmp bl, 00010001b ; Did we rotate four times?
jne DoNextXCirc ; If not then do the next pixel
inc di ; Otherwise bump the Video MemPtr
DoNextXCirc:
inc cx ; Next X
cmp cx, 320
jl ForXCirc
pop cx
mov ax, bp ; Get IterateCnt
mul cx ; DX:AX := IterateCnt * Y
add si, ax ; ColorCount := ColorCount + (IterateCnt * Y)
inc cx ; Next Y
cmp cx, 400
jl ForYCirc
ret
DoCircles endp
DoTiltCircles proc near
mov bl, 00010001b ; Plane Mask bit
mov di, 0 ; Video memory pointer
mov cx, 0 ; For Y := 0 to 399 do
ForYTiltCirc:
push cx
mov cx, 0 ; For X := 0 to 319 do
ForXTiltCirc:
mov ax, bp ; Get IterateCnt
mul cx ; DX:AX := IterateCnt * X
add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
mov dx, SC_INDEX ; Select the correct plane
mov ah, bl
mov al, MAP_MASK
out dx, ax
mov ax, si ; Poke Color
mov byte ptr es:[di], al
rol bl, 1 ; Rotate for next plane
cmp bl, 00010001b ; Did we rotate four times?
jne DoNextXTiltCirc ; If not then do the next pixel
inc di ; Otherwise bump the Video MemPtr
DoNextXTiltCirc:
inc cx ; Next X
cmp cx, 320
jl ForXTiltCirc
pop cx
mov ax, bp ; Get IterateCnt
mul cx ; DX:AX := IterateCnt * Y
sub si, ax ; ColorCount := ColorCount - (IterateCnt * Y)
inc cx ; Next Y
cmp cx, 400
jl ForYTiltCirc
ret
DoTiltCircles endp
DoSquares proc near
mov bl, 00010001b ; Plane Mask bit
mov di, 0 ; Video memory pointer
mov cx, 0 ; For Y := 0 to 399 do
ForYSqr:
mov CurrY, cx
push cx
mov cx, 0 ; For X := 0 to 319 do
ForXSqr:
mov CurrX, cx
mov ax, bp ; Get IterateCnt
mov dx, CurrY ; Get current Y
mul dx ; DX:AX := IterateCnt * Y
add si, ax ; ColorCount := ColorCount + (IterateCnt * Y)
mov dx, SC_INDEX ; Select the correct plane
mov ah, bl
mov al, MAP_MASK
out dx, ax
mov ax, si ; Poke Color
mov byte ptr es:[di], al
rol bl, 1 ; Rotate for next plane
cmp bl, 00010001b ; Did we rotate four times?
jne DoNextXSqr ; If not then do the next pixel
inc di ; Otherwise bump the Video MemPtr
DoNextXSqr:
inc cx ; Next X
cmp cx, 320
jl ForXSqr
pop cx
mov ax, bp ; Get IterateCnt
mov dx, CurrX ; Get current X
mul dx ; DX:AX := IterateCnt * X
add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
inc cx ; Next Y
cmp cx, 400
jl ForYSqr
ret
CurrX dw (?)
CurrY dw (?)
DoSquares endp
DoTiltSquares proc near
mov bl, 00010001b ; Plane Mask bit
mov di, 0 ; Video memory pointer
mov cx, 0 ; For Y := 0 to 399 do
ForYTiltSqr:
mov CurrTiltY, cx
push cx
mov cx, 0 ; For X := 0 to 319 do
ForXTiltSqr:
mov CurrTiltX, cx
mov ax, bp ; Get IterateCnt
mov dx, CurrTiltY ; Get current Y
mul dx ; DX:AX := IterateCnt * Y
add si, ax ; ColorCount := ColorCount + (IterateCnt * Y)
mov dx, SC_INDEX ; Select the correct plane
mov ah, bl
mov al, MAP_MASK
out dx, ax
mov ax, si ; Poke Color
mov byte ptr es:[di], al
rol bl, 1 ; Rotate for next plane
cmp bl, 00010001b ; Did we rotate four times?
jne DoNextXTiltSqr ; If not then do the next pixel
inc di ; Otherwise bump the Video MemPtr
DoNextXTiltSqr:
inc cx ; Next X
cmp cx, 320
jl ForXTiltSqr
pop cx
mov ax, bp ; Get IterateCnt
mov dx, CurrTiltX ; Get current X
mul dx ; DX:AX := IterateCnt * X
add si, ax ; ColorCount := ColorCount + (IterateCnt * X)
inc cx ; Next Y
cmp cx, 400
jl ForYTiltSqr
ret
CurrTiltX dw (?)
CurrTiltY dw (?)
DoTiltSquares endp
Randy proc near
; Returns a pseudo random integer in AX
GetTime:
mov ah, 2Ch
int 21h
mov ax, Random
add ax, 13
mul dx
add dx, 23
mul dx
shr dx, 1
shr dx, 1
shr dx, 1
add ax, dx
and ax, 7FFFh
mov Random, ax
ret
Random dw (?)
Randy endp
MakeRandomPalette proc near
call Randy
mov byte ptr RED, al
call Randy
mov byte ptr GREEN, al
call Randy
mov byte ptr BLUE, al
mov cx, 0
NextPal:
mov al, cl
mov dx, 03C8h ; Set Write PEL Address
out dx, al
inc dx
mov al, byte ptr RED ; Get RED
and al, 3Fh
out dx, al
mov al, byte ptr GREEN ; Get GREEN
and al, 3Fh
out dx, al
mov al, byte ptr BLUE ; Get BLUE
and al, 3Fh
out dx, al
inc byte ptr RED
inc byte ptr GREEN
inc byte ptr BLUE
inc cx
cmp cx, 256
jl NextPal
ret
RED db (?)
GREEN db (?)
BLUE db (?)
MakeRandomPalette endp
Set320x400Mode proc near
mov ax, 0013h
int 10h
mov dx, SC_INDEX
mov al, MEMORY_MODE
out dx, al
inc dx
in al, dx
and al, NOT 08h
or al, 04h
out dx, al
mov dx, GC_INDEX
mov al, GRAPHICS_MODE
out dx, al
inc dx
in al, dx
and al, NOT 10h
out dx, al
dec dx
mov al, MISCELLANEOUS
out dx, al
inc dx
in al, dx
and al, NOT 02h
out dx, al
CONSTANT_TO_INDEXED_REGISTER SC_INDEX, MAP_MASK, 0Fh
mov ax, VGA_SEGMENT
mov es, ax
sub di, di
mov ax, di
mov cx, 8000h
rep stosw
mov dx, CRTC_INDEX
mov al, MAX_SCAN_LINE
out dx, al
inc dx
in al, dx
and al, NOT 1Fh
out dx, al
dec dx
mov al, UNDERLINE
out dx, al
inc dx
in al, dx
and al, NOT 40h
out dx, al
dec dx
mov al, MODE_CONTROL
out dx, al
inc dx
in al, dx
or al, 40h
out dx, al
ret
Set320x400Mode endp
code ends
End Begin